package org.seanye.erp.view.timesheet;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

public class DateModel {
	private Date startDate;
	private int type = Calendar.YEAR;
	private List<DateModel> children = new ArrayList<DateModel>();

	public DateModel() {

	}

	public DateModel(Date statDate, int type) {
		this.startDate = statDate;
		this.type = type;
	}

	public Date computeStartDate() {
		if (startDate == null) {
			if (!getChildren().isEmpty()) {
				startDate = getChildren().get(0).getStartDate();
			}
		}
		return startDate;
	}

	public Date getStartDate() {
		return this.startDate;
	}

	public int getType() {
		return type;
	}

	public void setType(int type) {
		this.type = type;
	}

	public List<DateModel> getChildren() {
		return children;
	}

	public void setChildren(List<DateModel> children) {
		this.children = children;
	}

	public void addChild(DateModel dateModel) {
		this.children.add(dateModel);
	}

	@Override
	public String toString() {
		Calendar cal = Calendar.getInstance();
		cal.setFirstDayOfWeek(Calendar.MONDAY);
		if (computeStartDate() != null)
			cal.setTime(computeStartDate());
		switch (getType()) {
		case Calendar.YEAR:
			return "Year " + cal.get(getType());
		case Calendar.MONTH:
			return "Month " + (cal.get(getType()) + 1);
		case Calendar.WEEK_OF_MONTH:
			return "Week " + cal.get(getType());
		case Calendar.DAY_OF_WEEK:
			return "Date " + computeStartDate();
		default:
			break;
		}
		return "DateModel [children=" + children.size() + ", startDate="
				+ startDate + ", type=" + type + "]";
	}

	public static List<DateModel> recentYears(int startYear, int offset) {
		if (startYear < 1900 || startYear > 3000) {
			throw new IllegalArgumentException("Year is invalid");
		}
		List<DateModel> models = new ArrayList<DateModel>();
		for (int year = 0; year < offset; year++) {
			int currentYear = startYear + year;
			GregorianCalendar gc = new GregorianCalendar(currentYear, 1, 1);
			gc.setFirstDayOfWeek(Calendar.MONDAY);
			DateModel yearModel = new DateModel(gc.getTime(), Calendar.YEAR);
			int days = gc.isLeapYear(currentYear) ? 366 : 355;
			for (int m = 0; m < 12; m++) {
				DateModel monthModel = new DateModel();
				monthModel.setType(Calendar.MONTH);
				yearModel.addChild(monthModel);
			}
			for (int i = 1; i <= days; i++) {
				gc.set(GregorianCalendar.DAY_OF_YEAR, i);
				int dayOfWeekInMonth = gc.get(GregorianCalendar.WEEK_OF_MONTH);
				DateModel activeMonth = yearModel.getChildren().get(
						gc.get(GregorianCalendar.MONTH));
				List<DateModel> currentMonthWeeks = activeMonth.getChildren();
				if (gc.get(GregorianCalendar.DAY_OF_MONTH) == 1) {
					activeMonth.setStartDate(gc.getTime());
				}
				DateModel weekModel = null;
				if (currentMonthWeeks.size() < dayOfWeekInMonth) {
					weekModel = new DateModel();
					weekModel.setType(Calendar.WEEK_OF_MONTH);
					currentMonthWeeks.add(dayOfWeekInMonth - 1, weekModel);
				} else {
					weekModel = currentMonthWeeks.get(dayOfWeekInMonth - 1);
				}
				System.out.println(gc.get(GregorianCalendar.DAY_OF_WEEK) + "  "
						+ gc.getTime());
				if (gc.get(GregorianCalendar.DAY_OF_WEEK) == 1) {
					weekModel.setStartDate(gc.getTime());
				}
				DateModel dayModel = new DateModel(gc.getTime(),
						Calendar.DAY_OF_WEEK);
				weekModel.addChild(dayModel);
			}
			models.add(yearModel);
		}
		return models;
	}

	public void setStartDate(Date startDate) {
		this.startDate = startDate;
	}

	public static void main(String[] args) {
		DateModel m = new DateModel();
		m.recentYears(2008, 4);
	}
}
